﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;

namespace KZ400B.Controls
{
    public class OneStepAddtionStateV2
    {
        public OneStepAddtionStateV2(
            string aName
            , double addtion
            , double runSpeed
          )
        {
            m_AxleName = aName;
            m_Addtion = addtion;
            m_RunSpeed = runSpeed;
        }

        string m_AxleName;
        public string AxleName
        {
            get { return m_AxleName; }
            //set { m_AxleName = value; }
        }

        double m_Addtion;
        public double Addtion
        {
            get { return m_Addtion; }
            //set { m_Addtion = value; }
        }

        double m_RunSpeed;
        public double RunSpeed
        {
            get { return m_RunSpeed; }
            //set { m_RunSpeed = value; }
        }


    }

    public class OneStepAddManagerV2
    {
        static bool m_isR = false;
        static object m_isRlk = new object();

        public static bool IsRunning
        {
            get { lock (m_isRlk) { return OneStepAddManagerV2.m_isR; } }
            set { lock (m_isRlk) { OneStepAddManagerV2.m_isR = value; } }
        }

        static Thread m_tR = null;
        //static AxleActionManage m_rMg = new AxleActionManage();
        //static AxleActionManage m_sMg = new AxleActionManage();
        public static void Start()
        {
            if (IsRunning) return;
            if (m_tR == null)
            {
                //m_rMg.Regist(AxleCacheManager.AxleList, AxleActions.RunFinish);
                //m_sMg.Regist(AxleCacheManager.AxleList, AxleActions.StopFinish);
                IsRunning = true;
                m_tR = new Thread(new ThreadStart(proc));
                m_tR.Start();
            }
        }

        public static void Stop()
        {
            IsRunning = false;
            try
            {
                //m_rMg.UnRegist();
                //m_sMg.UnRegist();
                m_tR.Join();
                m_tR = null;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        static Queue m_addQueue = Queue.Synchronized(new Queue());
        public static void addOneState(OneStepAddtionStateV2 state)
        {
            if (!IsRunning) return;
            lock (m_addQueue.SyncRoot)
            {
                if (m_addQueue.Count < 10000 && state != null)
                {
                    m_addQueue.Enqueue(state);
                }
            }
        }
        static void proc()
        {
            while (IsRunning)
            {
                OneStepAddtionStateV2 state = null;
                lock (m_addQueue.SyncRoot)
                {
                    if (m_addQueue.Count > 0)
                    {
                        state = m_addQueue.Dequeue() as OneStepAddtionStateV2;
                    }
                }
                if (state != null)
                {
                    doOSAddtion(state);
                }
                else
                {
                    Thread.Sleep(200);
                }
            }
        }
        static void setState(string state)
        {
            KZ400B.Data.AxleStateBarMsg.Instance.AxleState = state;
        }
        static bool m_isPmsErr = false;
        static void doOSAddtion(OneStepAddtionStateV2 state)
        {
            int direct = 0;
            double totalStep = 0.0F;
            bool bRst = false;
            try
            {
                if (state == null || state.Addtion == 0.0F) return;
                string aName = state.AxleName;
                totalStep = state.Addtion;
                double runSpeed = state.RunSpeed;//AxleCacheManager.AxleList[aName].RunSpeed;
                bool isForward = state.Addtion >= 0;
                direct = isForward
                    ? (int)Axle.Direction.ForwardDirection.Value
                    : (int)Axle.Direction.BackDirection.Value;
                totalStep = isForward ? state.Addtion : 0 - state.Addtion;

                //double rTS = state.Addtion;
                if (AxleCacheManager.AxleList[aName].DisplayPosition
                    + AxleCacheManager.AxleList[aName].DisplayRelativeZero
                    + state.Addtion < 0)
                {
                    setState("运行目标超越绝对零位!");
                    return;
                }
                AxleCacheManager.AxleList[aName].Addtion = totalStep;
                Axle.Direction dirt = new Axle.Direction(direct);
                double pwm = AxleCacheManager.AxleList[aName].getRunPwm(runSpeed);
                bool setRst = AxleManager.ParameterSetting(aName
                    , new Axle.Direction(direct)
                    , AxleCacheManager.AxleList[aName].getRunPwm(runSpeed)
                    , AxleCacheManager.AxleList[aName].TotalStep
                    , m_isPmsErr
                    );
                m_isPmsErr = !setRst;
                //AxleCacheManager.AxleList[aName].OnestepAddtion = totalStep;
                if (setRst)
                {
                    setState(
                    string.Format("参数设置({0}|[{1}]|{2}|{3})成功"
                        , aName, dirt.ToString()
                        , pwm
                        , AxleCacheManager.AxleList[aName].TotalStep
                        )
                    );
                    AxleCacheManager.Update(AxleCacheManager.AxleList[aName]);
                    bRst = AxleManager.Run(aName);
                    if (bRst)
                    {
                        //while (!m_rMg.IsActionReady(aName) && !m_sMg.IsActionReady(aName))
                        //{
                        //    Thread.Sleep(50);
                        //}
                        //m_rMg.ResetAction(aName);
                        //m_sMg.ResetAction(aName);
                    }
                }
                else
                {
                    setState(
                    string.Format("参数设置({0}|[{1}]|{2}|{3})失败"
                        , aName, dirt.ToString()
                        , pwm
                        , AxleCacheManager.AxleList[aName].TotalStep
                        )
                    );
                }
                //}//if int.tryparse totalstep

            }
            catch (Exception ex)
            {
                setState(
                                string.Format("参数设置错误:({0})"
                                    , ex.Message
                                    )
                                );
            }
            finally
            {
                if (bRst)
                {
                    //state.AxleState.setBtnState_AxleRunning();
                }

            }
        }
    }


    public class OneStepAddtionState
    {
        public OneStepAddtionState(
            string aName
            , double addtion
            ,double runSpeed
            , nAxleState control
          )
        {
            m_AxleName = aName;
            m_Addtion = addtion;
            m_RunSpeed = runSpeed;
            m_AxleState = control;
        }

        string m_AxleName;
        public string AxleName
        {
            get { return m_AxleName; }
            //set { m_AxleName = value; }
        }

        double m_Addtion;
        public double Addtion
        {
            get { return m_Addtion; }
            //set { m_Addtion = value; }
        }

        double m_RunSpeed;
        public double RunSpeed
        {
            get { return m_RunSpeed; }
            //set { m_RunSpeed = value; }
        }

        nAxleState m_AxleState;

        public nAxleState AxleState
        {
            get { return m_AxleState; }
            //set { m_AxleState = value; }
        }
    }

    public class OneStepAddManager
    {
        static bool m_isR = false;
        static object m_isRlk = new object();

        public static bool IsRunning
        {
            get { lock (m_isRlk) { return OneStepAddManager.m_isR; } }
            set { lock (m_isRlk) { OneStepAddManager.m_isR = value; } }
        }

        static Thread m_tR = null;
        //static AxleActionManage m_rMg = new AxleActionManage();
        //static AxleActionManage m_sMg = new AxleActionManage();
        public static void Start()
        {
            if (IsRunning) return;
            if (m_tR == null)
            {
                //m_rMg.Regist(AxleCacheManager.AxleList, AxleActions.RunFinish);
                //m_sMg.Regist(AxleCacheManager.AxleList, AxleActions.StopFinish);
                IsRunning = true;
                m_tR = new Thread(new ThreadStart(proc));
                m_tR.Start();
            }
        }

        public static void Stop()
        {
            IsRunning = false;
            try
            {
                //m_rMg.UnRegist();
                //m_sMg.UnRegist();
                m_tR.Join();
                m_tR = null;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        static Queue m_addQueue = Queue.Synchronized(new Queue());
        public static void addOneState(OneStepAddtionState state)
        {
            if (!IsRunning) return;
            lock (m_addQueue.SyncRoot)
            {
                if (m_addQueue.Count < 10000 && state != null)
                {
                    m_addQueue.Enqueue(state);
                }
            }
        }
        static void proc()
        {
            while (IsRunning)
            {
                OneStepAddtionState state = null;
                lock (m_addQueue.SyncRoot)
                {
                    if (m_addQueue.Count > 0)
                    {
                        state = m_addQueue.Dequeue() as OneStepAddtionState;
                    }
                }
                if (state != null)
                {
                    doOSAddtion(state);
                }
                else
                {
                    Thread.Sleep(200);
                }
            }
        }
        static bool m_isPmsErr = false;
        static void doOSAddtion(OneStepAddtionState state)
        {
            int direct = 0;
            double totalStep = 0.0F;
            bool bRst = false;
            try
            {
                if (state == null || state.Addtion == 0.0F) return;
                string aName = state.AxleName;
                totalStep = state.Addtion;
                double runSpeed = state.RunSpeed;//AxleCacheManager.AxleList[aName].RunSpeed;
                bool isForward = state.Addtion >= 0;
                direct = isForward
                    ? (int)Axle.Direction.ForwardDirection.Value
                    : (int)Axle.Direction.BackDirection.Value;
                totalStep = isForward ? state.Addtion : 0 - state.Addtion;

                //double rTS = state.Addtion;
                if (AxleCacheManager.AxleList[aName].DisplayPosition
                    + AxleCacheManager.AxleList[aName].DisplayRelativeZero
                    + state.Addtion < 0)
                {
                    state.AxleState.setState("运行目标超越绝对零位!");
                    return;
                }
                AxleCacheManager.AxleList[aName].Addtion = totalStep;
                Axle.Direction dirt = new Axle.Direction(direct);
                double pwm = AxleCacheManager.AxleList[aName].getRunPwm(runSpeed);
                bool setRst = AxleManager.ParameterSetting(aName
                    , new Axle.Direction(direct)
                    , AxleCacheManager.AxleList[aName].getRunPwm(runSpeed)
                    , AxleCacheManager.AxleList[aName].TotalStep
                    ,m_isPmsErr
                    );
                m_isPmsErr = !setRst;
                //AxleCacheManager.AxleList[aName].OnestepAddtion = totalStep;
                if (setRst)
                {
                    state.AxleState.setState(
                    string.Format("参数设置({0}|[{1}]|{2}|{3})成功"
                        , aName, dirt.ToString()
                        , pwm
                        , AxleCacheManager.AxleList[aName].TotalStep
                        )
                    );
                    AxleCacheManager.Update(AxleCacheManager.AxleList[aName]);
                    bRst = AxleManager.Run(aName);
                    if (bRst)
                    {
                        //while (!m_rMg.IsActionReady(aName) && !m_sMg.IsActionReady(aName))
                        //{
                        //    Thread.Sleep(50);
                        //}
                        //m_rMg.ResetAction(aName);
                        //m_sMg.ResetAction(aName);
                    }
                }
                else
                {
                    state.AxleState.setState(
                    string.Format("参数设置({0}|[{1}]|{2}|{3})失败"
                        , aName, dirt.ToString()
                        , pwm
                        , AxleCacheManager.AxleList[aName].TotalStep
                        )
                    );
                }
                //}//if int.tryparse totalstep

            }
            catch (Exception ex)
            {
                state.AxleState.setState(
                                string.Format("参数设置错误:({0})"
                                    , ex.Message
                                    )
                                );
            }
            finally
            {
                if (bRst)
                {
                    //state.AxleState.setBtnState_AxleRunning();
                }
                
            }
        }
    }
}
